﻿using System;
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks; 
using Secs4Net;

namespace PXFAP.SecsNetWinApplication
{
    public class SecsGemWarp
    {
        public static SecsGemWarp Configure(Action<SecsGemWarp> action)
        {
            if (action == null)
                throw new ArgumentNullException("action");

            var secsGem = new SecsGemWarp();
            action?.Invoke(secsGem);
            return secsGem;
        }

        public HsmsConnection Connector { get; set; }
        public SecsGem SecsGem { get; set; }
        public CancellationTokenSource CancellationToken { get; set; }  

        public event Action<SecsGemWarp, SecsGemOptions> OnStarted;

        public event Action<PrimaryMessageWrapper> OnReceivePrimaryMessaged;

        public async void StartAsync(SecsGemOptions options)
        {
#pragma warning disable CS4014 // 由于此调用不会等待，因此在调用完成前将继续执行当前方法
            Task.Run(async () =>
            {
                _ = Connector.StartAsync(CancellationToken.Token);
                OnStarted?.Invoke(this, options);

                try
                {
                    await foreach (var primaryMessage in SecsGem.GetPrimaryMessageAsync(CancellationToken.Token))
                    {
                        OnReceivePrimaryMessaged?.Invoke(primaryMessage);
                    }
                }
                catch (OperationCanceledException)
                {

                }
            });
#pragma warning restore CS4014 // 由于此调用不会等待，因此在调用完成前将继续执行当前方法
        }

        public async void Dispose(Action callback)
        {
            if (!CancellationToken.IsCancellationRequested)
            {
                CancellationToken.Cancel();
                CancellationToken.Dispose();
            }
            if (Connector is not null)
            {
                await Connector.DisposeAsync();
            }
            SecsGem?.Dispose();
            CancellationToken = new CancellationTokenSource();
            SecsGem = null;
            
            // 机台下线 回调
            callback?.Invoke();
        }
    }
}
